﻿using EasyAdmin.Application.Contracts.Systems.Auth;
using EasyAdmin.Application.Contracts.Systems.Auth.Dtos;
using EasyAdmin.Domain.Entities.Systems;
using EasyCore.App;
using EasyCore.Application;
using EasyCore.Authentications;
using EasyCore.Authentications.Dtos;
using EasyCore.UnifyResult;
using EasyCore.UnifyResult.Exceptions;
using EasyCore.Utils.Images.Captcha;
using Masuit.Tools.Security;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using Yitter.IdGenerator;

namespace EasyAdmin.Application.Systems
{
    /// <summary>
    /// 用户认证服务
    /// </summary>
    public class AuthAppService : AppService, IAuthAppService
    {
        private ISqlSugarRepository<SysUser> _userRepo { get; set; }
        private IAuthTokenService _authTokenService { get; set; }

        public AuthAppService(ISqlSugarRepository<SysUser> userRepao, IAuthTokenService authTokenService)
        {
            _userRepo = userRepao;
            _authTokenService = authTokenService;
        }

        /// <summary>
        /// 获得图形验证码
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<PicValidCodeOutput> GetCaptchaInfo()
        {
            var captchaInfo = CaptchaUtil.CreateCaptcha(CaptchaType.CHAR, 4, 100, 38);
            long captchaId = YitIdHelper.NextId(); //获得验证码序列号
            EasyApp.Cache.Add(string.Format("Captcha:{0}", captchaId), captchaInfo.Code, 60 * 3);//添加到缓存
            return new PicValidCodeOutput() { ValidCodeReqNo = captchaId.ToString(), ValidCodeBase64 = captchaInfo.Base64Str };
        }

        /// <summary>
        /// 用户密码登录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<LoginOutput> Login(LoginInput input)
        {
            //if(string.IsNullOrWhiteSpace(input.ValidCodeReqNo)) throw new OperateBusinessException("验证码错误");
            //string captchaKey = string.Format("Captcha:{0}", input.ValidCodeReqNo);           
            //if (EasyApp.Cache.ContainsKey(captchaKey)) throw new OperateBusinessException("验证码错误");
            //var validCode = EasyApp.Cache.Get<string>(captchaKey);
            //if (input.ValidCode.ToLower() != validCode.ToLower()) throw new OperateBusinessException("验证码错误");
            var user = await _userRepo.FirstOrDefaultAsync(m => m.Account == input.Account && m.Password == input.Password.SHA256());
           // EasyApp.Cache.Remove(captchaKey);//登录认证完后，不管是否登录成功，还是不存功，则去掉验证码缓存
            if (user == null) throw new BusinessException("用户名或密码错误");
            if (user.IsDisabled) throw new BusinessException("用户被禁用，请联系管理员");
            Dictionary<string, string> keyValues = new Dictionary<string, string>();
            keyValues.Add("id", user.Id.ToString());
            keyValues.Add("name", user.Name);
            keyValues.Add("NickName", user.Nickname);
            var authToken = await _authTokenService.CreateAuthTokenAsync(keyValues);
            var refreshAuthToken = await _authTokenService.RefreshAuthTokenAsync(authToken);
            LoginOutput result = new LoginOutput();
            result.Account = user.Account;
            result.Name = user.Name;
            result.Token = authToken.AccessToken; //访问令牌
            result.RefToken = authToken.RefreshToken; //刷新令牌
            return result;
        }

        /// <summary>
        /// 用户手机号码登录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<LoginOutput> LoginByPhone(LoginByPhoneInput input)
        {
            throw new NotImplementedException("当前功能未实现");
        }


        /// <summary>
        /// 获得登录用户信息
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task<LoginUserOutput> GetLoginUser()
        {
            // EasyApp.UserId
            throw new NotImplementedException();
        }

        /// <summary>
        /// 刷新令牌
        /// </summary>
        /// <param name="dto">原访问令牌</param>
        /// <returns></returns>
        public async Task<AuthTokenDto> RefreshToken([FromBody] AuthTokenDto dto)
        {
            var token = await _authTokenService.RefreshAuthTokenAsync(dto);
            return token;
        }

        /// <summary>
        /// 退出登录
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task LoginOut()
        {
            throw new NotImplementedException();
        }
    }
}
